package com.bookocean.infrastructure.persistence.repository;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bookocean.application.exception.BusinessException;
import com.bookocean.application.exception.WeChatErrorCodeEnum;
import com.bookocean.controller.dto.BookDto;
import com.bookocean.controller.dto.BookQuoteDto;
import com.bookocean.domain.dto.BookCoverDto;
import com.bookocean.domain.repository.BookRepository;
import com.bookocean.domain.repository.BookLikeRepository;
import com.bookocean.domain.repository.BookCommentRepository;
import com.bookocean.domain.repository.BookFavoriteRepository;
import com.bookocean.infrastructure.converter.BookCoverConverter;
import com.bookocean.infrastructure.persistence.converter.BookConverter;
import com.bookocean.infrastructure.persistence.mapper.BookCoverMapper;
import com.bookocean.infrastructure.persistence.mapper.BookMapper;
import com.bookocean.infrastructure.persistence.mapper.BookQuoteMapper;
import com.bookocean.infrastructure.persistence.po.BookCoverPO;
import com.bookocean.infrastructure.persistence.po.BookPO;
import com.bookocean.infrastructure.persistence.po.BookQuotePO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 书籍仓储实现类
 *
 * @author BookOcean
 * @since 2024-01-01
 */
@Slf4j
@Repository
@RequiredArgsConstructor
public class BookRepositoryImpl implements BookRepository {

    private final BookMapper bookMapper;

    private final BookQuoteMapper bookQuoteMapper;

    private final BookCoverMapper bookCoverMapper;

    private final BookLikeRepository bookLikeRepository;

    private final BookCommentRepository bookCommentRepository;

    private final BookFavoriteRepository bookFavoriteRepository;

    @Override
    public BookDto getBookInfoByName(String title) {
        // 参数校验
        if (StrUtil.isBlank(title)) {
            log.warn("查询书籍信息时，书名不能为空");
            return null;
        }
        try {
            LambdaQueryWrapper<BookPO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(BookPO::getTitle, title.trim());
            BookPO bookInfo = bookMapper.selectOne(queryWrapper);
            if (ObjectUtil.isEmpty(bookInfo)) {
                log.debug("未找到书名为 [{}] 的书籍信息", title);
                return null;
            }
            return BookConverter.toDto(bookInfo);
        } catch (Exception e) {
            throw new BusinessException(WeChatErrorCodeEnum.GET_BOOK_INFO_ERROR);
        }
    }

    @Override
    public List<BookDto> searchBooksByName(String title) {
        // 参数校验
        if (StrUtil.isBlank(title)) {
            log.warn("搜索书籍时，书名关键词不能为空");
            return new ArrayList<>();
        }
        try {
            LambdaQueryWrapper<BookPO> queryWrapper = new LambdaQueryWrapper<>();
            // 模糊搜索，限制返回数量
            queryWrapper.like(BookPO::getTitle, title.trim())
                    .orderByDesc(BookPO::getCreatedAt)
                    .last("LIMIT 10");
            List<BookPO> bookList = bookMapper.selectList(queryWrapper);
            return bookList.stream()
                    .map(BookConverter::toDto)
                    .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("搜索书籍失败，关键词: {}, 错误: {}", title, e.getMessage(), e);
            throw new BusinessException(WeChatErrorCodeEnum.GET_BOOK_INFO_ERROR);
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public BookDto saveBookInfo(BookDto bookDto) {
        // 参数校验
        if (ObjectUtil.isEmpty(bookDto) || StrUtil.isBlank(bookDto.getTitle())) {
            log.warn("保存书籍信息时，书籍信息或书名不能为空");
            return null;
        }
        try {
            BookPO bookPo = BookConverter.toPo(bookDto);
            // 设置创建时间
            bookPo.setCreatedAt(LocalDateTime.now());
            bookMapper.insert(bookPo);
            return BookConverter.toDto(bookPo);
        } catch (Exception e) {
            log.error("保存书籍信息失败，书名: {}, 错误: {}", bookDto.getTitle(), e.getMessage(), e);
            throw new BusinessException(WeChatErrorCodeEnum.SAVE_BOOK_ERROR);
        }
    }

    @Override
    public BookDto getBookById(Long bookId) {
        if (ObjectUtil.isEmpty(bookId)) {
            return null;
        }
        try {
            BookPO bookPo = bookMapper.selectById(bookId);
            if (ObjectUtil.isEmpty(bookPo)) {
                return null;
            }
            return BookConverter.toDto(bookPo);
        } catch (Exception e) {
            throw new BusinessException(WeChatErrorCodeEnum.GET_BOOK_INFO_ERROR);
        }
    }

    @Override
    public BookDto getEnhancedBookById(Long bookId, Long userId) {
        if (ObjectUtil.isEmpty(bookId)) {
            return null;
        }
        try {
            // 获取基础书籍信息
            BookPO bookPo = bookMapper.selectById(bookId);
            if (ObjectUtil.isEmpty(bookPo)) {
                return null;
            }
            
            BookDto bookDto = BookConverter.toDto(bookPo);
            
            // 查询该书籍的所有书摘ID
            LambdaQueryWrapper<BookQuotePO> quoteWrapper = new LambdaQueryWrapper<>();
            quoteWrapper.eq(BookQuotePO::getBookId, bookId);
            List<BookQuotePO> quotes = bookQuoteMapper.selectList(quoteWrapper);
            
            if (quotes.isEmpty()) {
                // 如果没有书摘，设置默认值
                bookDto.setTotalQuoteCount(0);
                bookDto.setTotalLikeCount(0);
                bookDto.setTotalCommentCount(0);
                bookDto.setTotalFavoriteCount(0);
                bookDto.setIsLikedByCurrentUser(false);
                bookDto.setIsFavoritedByCurrentUser(false);
                return bookDto;
            }
            
            // 获取所有书摘ID列表
            List<Long> quoteIds = quotes.stream()
                    .map(BookQuotePO::getQuoteId)
                    .collect(Collectors.toList());
            
            // 统计书摘数量
            bookDto.setTotalQuoteCount(quotes.size());
            
            // 统计总点赞数
            Integer totalLikes = 0;
            for (Long quoteId : quoteIds) {
                totalLikes += bookLikeRepository.getLikeCount(quoteId);
            }
            bookDto.setTotalLikeCount(totalLikes);
            
            // 统计总评论数
            Integer totalComments = 0;
            for (Long quoteId : quoteIds) {
                totalComments += bookCommentRepository.getCommentCount(quoteId);
            }
            bookDto.setTotalCommentCount(totalComments);
            
            // 统计总收藏数
            Integer totalFavorites = 0;
            for (Long quoteId : quoteIds) {
                totalFavorites += bookFavoriteRepository.getFavoriteCount(quoteId);
            }
            bookDto.setTotalFavoriteCount(totalFavorites);
            
            // 检查当前用户的交互状态
            if (userId != null) {
                boolean isLiked = false;
                boolean isFavorited = false;
                
                for (Long quoteId : quoteIds) {
                    if (!isLiked && bookLikeRepository.existsByQuoteIdAndUserId(quoteId, userId)) {
                        isLiked = true;
                    }
                    if (!isFavorited && bookFavoriteRepository.existsByQuoteIdAndUserId(quoteId, userId)) {
                        isFavorited = true;
                    }
                    // 如果两个状态都已确定，可以提前退出循环
                    if (isLiked && isFavorited) {
                        break;
                    }
                }
                
                bookDto.setIsLikedByCurrentUser(isLiked);
                bookDto.setIsFavoritedByCurrentUser(isFavorited);
            } else {
                bookDto.setIsLikedByCurrentUser(false);
                bookDto.setIsFavoritedByCurrentUser(false);
            }
            
            return bookDto;
        } catch (Exception e) {
            log.error("获取增强书籍信息失败: bookId={}, userId={}, 错误: {}", bookId, userId, e.getMessage(), e);
            throw new BusinessException(WeChatErrorCodeEnum.GET_BOOK_INFO_ERROR);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BookQuoteDto saveQuoteInfo(BookQuoteDto bookQuoteDto) {
        // 参数校验
        if (ObjectUtil.isEmpty(bookQuoteDto)) {
            log.warn("保存书摘信息时，书摘信息不能为空");
            return null;
        }
        if (ObjectUtil.isEmpty(bookQuoteDto.getBookId())) {
            log.warn("保存书摘信息时，书籍ID不能为空");
            return null;
        }
        if (ObjectUtil.isEmpty(bookQuoteDto.getUserId())) {
            log.warn("保存书摘信息时，用户ID不能为空");
            return null;
        }
        if (StrUtil.isBlank(bookQuoteDto.getContent())) {
            log.warn("保存书摘信息时，书摘内容不能为空");
            return null;
        }
        try {
            BookQuotePO bookQuotePo = BookConverter.toBookQuotePo(bookQuoteDto);
            // 设置创建时间和更新时间
            LocalDateTime now = LocalDateTime.now();
            bookQuotePo.setCreatedAt(now);
            bookQuotePo.setUpdatedAt(now);
            bookQuoteMapper.insert(bookQuotePo);
            return BookConverter.toBookQuoteDto(bookQuotePo);
        } catch (Exception e) {
            log.error("保存书摘信息失败，错误: {}", e.getMessage(), e);
            throw new BusinessException(WeChatErrorCodeEnum.SAVE_QUOTE_ERROR);
        }
    }

    @Override
    public List<BookQuoteDto> getUserQuotes(Integer page, Integer pageSize, Long userId) {
        if (ObjectUtil.isEmpty(userId)) {
            log.warn("获取我的书摘时，用户ID不能为空，userId: {}", userId);
            throw new BusinessException(WeChatErrorCodeEnum.PARAM_ERROR, "用户ID不能为空");
        }
        try {
            LambdaQueryWrapper<BookQuotePO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(BookQuotePO::getUserId, userId)
                    .orderByDesc(BookQuotePO::getCreatedAt);
            
            // 分页查询
            Page<BookQuotePO> pageParam = new Page<>(page, pageSize);
            Page<BookQuotePO> result = bookQuoteMapper.selectPage(pageParam, queryWrapper);
            
            return result.getRecords().stream()
                    .map(this::convertToEnhancedBookQuoteDto)
                    .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("获取我的书摘失败，用户ID: {}, 错误: {}", userId, e.getMessage(), e);
            throw new BusinessException(WeChatErrorCodeEnum.GET_BOOK_INFO_ERROR);
        }
    }

    /**
     * 转换为增强的书摘DTO（包含书籍信息和统计数据）
     */
    private BookQuoteDto convertToEnhancedBookQuoteDto(BookQuotePO quotePo) {
        BookQuoteDto dto = BookConverter.toBookQuoteDto(quotePo);
        
        // 查询关联的书籍信息
        if (quotePo.getBookId() != null) {
            try {
                BookPO book = bookMapper.selectById(quotePo.getBookId());
                if (book != null) {
                    dto.setBookTitle(book.getTitle());
                    dto.setBookAuthor(book.getAuthor());
                    dto.setBookCoverUrl(book.getCoverUrl());
                }
            } catch (Exception e) {
                log.warn("查询书籍信息失败，bookId: {}, error: {}", quotePo.getBookId(), e.getMessage());
            }
        }
        
        // 设置默认统计信息（后续可以查询真实的统计数据）
        dto.setLikeCount(0);
        dto.setCommentCount(0);
        dto.setFavoriteCount(0);
        
        return dto;
    }

    @Override
    public BookCoverDto[] getCoversByType(Integer imageType, String userId) {
        if (ObjectUtil.isEmpty(imageType)) {
            log.warn("获取封面素材时，图片类型不能为空");
            return new BookCoverDto[0];
        }
        try {
            LambdaQueryWrapper<BookCoverPO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(BookCoverPO::getImageType, imageType)
                    .and(wrapper -> wrapper.eq(BookCoverPO::getIsPublic, 1)
                            .or()
                            .eq(BookCoverPO::getUserId, userId))
                    .orderByDesc(BookCoverPO::getCreatedAt);
            
            List<BookCoverPO> coverList = bookCoverMapper.selectList(queryWrapper);
            return coverList.stream()
                    .map(BookCoverConverter::toDto)
                    .toArray(BookCoverDto[]::new);
        } catch (Exception e) {
            log.error("获取封面素材失败，图片类型: {}, 用户ID: {}, 错误: {}", imageType, userId, e.getMessage(), e);
            throw new BusinessException(WeChatErrorCodeEnum.GET_BOOK_INFO_ERROR);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BookCoverDto saveCover(BookCoverDto coverDto) {
        if (ObjectUtil.isEmpty(coverDto) || StrUtil.isBlank(coverDto.getCoverUrl())) {
            log.warn("保存封面素材时，封面信息或封面URL不能为空");
            return null;
        }
        try {
            BookCoverPO coverPo = BookCoverConverter.toPo(coverDto);
            LocalDateTime now = LocalDateTime.now();
            coverPo.setCreatedAt(now);
            coverPo.setUpdatedAt(now);
            bookCoverMapper.insert(coverPo);
            return BookCoverConverter.toDto(coverPo);
        } catch (Exception e) {
            log.error("保存封面素材失败，错误: {}", e.getMessage(), e);
            throw new BusinessException(WeChatErrorCodeEnum.SAVE_BOOK_ERROR);
        }
    }
}
